package com.zephyr.monitorservice.service;

import com.zephyr.monitorservice.entity.JvmMetric;
import com.zephyr.monitorservice.repository.JvmMetricRepository;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.lang.management.MemoryUsage;
import java.time.LocalDateTime;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class JmxMonitorService {

    private final JvmMetricRepository repository;

    @Value("${monitor.target.host}")
    private String host;

    @Value("${monitor.target.port}")
    private int port;

    private String jmxUrl;

    @PostConstruct
    public void init() {
        this.jmxUrl = String.format("service:jmx:rmi:///jndi/rmi://%s:%d/jmxrmi", host, port);
    }

    @Scheduled(fixedRate = 5000) // 每 5 秒采集一次
    public void collectMetrics() {
        try {
            JMXServiceURL url = new JMXServiceURL(jmxUrl);
            JMXConnector connector = JMXConnectorFactory.connect(url, Map.of());
            MBeanServerConnection mBeanConn = connector.getMBeanServerConnection();

            // 堆内存
            ObjectName heapObj = new ObjectName("java.lang:type=Memory");
            MemoryUsage heapMemoryUsage =
                    MemoryUsage.from((CompositeDataSupport) mBeanConn.getAttribute(heapObj, "HeapMemoryUsage"));

            // 线程数
            ObjectName threadObj = new ObjectName("java.lang:type=Threading");
            Integer threadCount = (Integer) mBeanConn.getAttribute(threadObj, "ThreadCount");

            // 系统负载
            ObjectName osObj = new ObjectName("java.lang:type=OperatingSystem");
            Double systemLoad = (Double) mBeanConn.getAttribute(osObj, "SystemLoadAverage");

            // 保存到数据库
            JvmMetric metric = new JvmMetric();
            metric.setHeapMemoryUsed(heapMemoryUsage.getUsed() / 1024.0 / 1024);
            metric.setHeapMemoryMax(heapMemoryUsage.getMax() / 1024.0 / 1024);
            metric.setThreadCount(threadCount);
            metric.setSystemLoad(systemLoad);
            metric.setCollectedAt(LocalDateTime.now());

            repository.save(metric);

            connector.close();
            System.out.println("✅ 采集成功: " + metric);
        } catch (Exception e) {
            System.err.println("❌ JMX采集失败: " + e.getMessage());
        }
    }
}